/*
 * Copyright 2009 Zero Separation
 *
 *     This file is part of PDSSQLService.
 *
 *  PDSSQLService is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  PDSSQLService is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with PDSSQLService.  If not, see <http://www.gnu.org/licenses/>.
 *
 */


package com.zero_separation.pds.sql;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * After the call has been made to the SQL database then if there was an
 * {@code SQLResultRunner} specified it will be called with an {@code SQLResult}
 * object containing the result of the SQL query.
 *
 * @author Tim Boura - Zero Separation
 */
public class SQLResult {

    public enum Result {
        SUCCESS,
        SQL_FAILURE,
        CONNECTION_FAILURE,
        OTHER_FAILURE
    }

    Result result;
    ResultSet resultSet;
    ResultSet generatedKeys;
    int updateCount;
    Throwable failure;
    SQLStatement query;

    SQLResult(
            Result result,
            ResultSet resultSet,
            ResultSet generatedKeys,
            int updateCount,
            Throwable failure,
            SQLStatement query) {
        try {
            this.result = result;
            if (resultSet == null)
                this.resultSet = null;
            else
                this.resultSet = new ClonedResultSet(resultSet);
            if (generatedKeys == null)
                this.generatedKeys = null;
            else
                this.generatedKeys = new ClonedResultSet(generatedKeys);
            this.updateCount = updateCount;
            this.failure = failure;
            this.query = query;
        } catch (SQLException ex) {
            this.result = SQLResult.Result.SQL_FAILURE;
            this.resultSet = null;
            this.generatedKeys = null;
            this.updateCount = -1;
            this.failure = failure;
            this.query = query;
        }
    }

    /**
     * The overall success or failure of the SQL statement
     *
     * @return A {@code Result} showing whether the SQL statement succeeded or failed
     */
    public Result getResult() {
        return result;
    }

    /**
     * Retrieves the result as a ResultSet object. Note that the maximum number
     * of rows returned is configured in the system and no more can be retrieved
     * from a query once it has executed.
     * 
     * The SQL query used will need to be structured to paginate results as required.
     * 
     * @return The current result as a ResultSet object or null if the result is
     * an update count or there are no more results 
     */
    public ResultSet getResultSet() {
        return resultSet;
    }

    /**
     * Retrieves any auto-generated keys created as a result of executing this
     * Statement object. If this Statement object did not generate any keys, an
     * empty ResultSet  object is returned.
     *
     * Note: If the columns which represent the auto-generated keys were not
     * specified, the JDBC driver implementation will determine the columns
     * which best represent the auto-generated keys.
     *
     * @return A ResultSet object containing the auto-generated key(s) generated
     * by the execution of this Statement object
     */
    public ResultSet getGeneratedKeys() {
        return generatedKeys;
    }

    /**
     * Retrieves the current result as an update count; if the result is a
     * ResultSet object or there are no more results, -1 is returned.
     *
     * @return The current result as an update count; -1 if the current result
     * is a ResultSet object or there are no more results
     */
    public int getUpdateCount() {
        return updateCount;
    }


    /**
     * Returns any exception that may have been recorded that was relevant to why
     * a failure may have occurred.
     *
     * @return Any exception relevant to a reported failure or null if none.
     */
    public Throwable getFailure() {
        return failure;
    }

    /**
     * Returns the query to which this object is the result.
     *
     * @return The SQLStatement used to launch this query.
     */
    public SQLStatement getQuery() {
        return query;
    }
}
